package com.ruoyi.shoufang.utils;

import com.alibaba.nacos.shaded.com.google.common.base.Joiner;
import com.sun.mail.util.MailSSLSocketFactory;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * TODO
 * email工具类
 * @author xuda
 * @date 2023/5/10 14:38
 */
public class SendEmailUtils {

    @Value("${resources.path}")
    private String staticFilePath;

    // 发送邮件
    public static void sendEmail(Map<String,Object> data) throws Exception {
        final String from = "1174013501@qq.com";//给用户发送邮件的邮箱
        final String username = "1174013501@qq.com";//邮箱的用户名
        final String password = "axisuzdlidwniiai";//邮箱授权码
        final String host = "smtp.qq.com";//发送邮件的服务器地址
        final String title = "维数公寓";//邮件主题
        final String to = (String) data.get("toemail");//接收人邮箱
        //配置
        Properties properties = new Properties();
        properties.setProperty("mail.host","smtp.qq.com");//设置qq邮件服务器
        properties.setProperty("mail.transport.protocol","smtp");//邮件发送协议
        properties.setProperty("mail.smtp.auth","true"); //需要验证用户名和密码
        //SSL加密
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        properties.put("mail.smtp.ssl.enable",true);
        properties.put("mail.smtp.ssl.socketFactory",sf);
        //创建邮件程序所需环境信息session对象
        Session session = Session.getDefaultInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });
        //开启session的debug模式，可以查看程序发送运行状态
        session.setDebug(true);
        //通过Session得到transport对象
        Transport transport = session.getTransport();
        //使用用户名和授权码连接服务器
        transport.connect(host,username,password);
        //写邮件
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress(from));//指明发件人
        message.setRecipient(Message.RecipientType.TO,new InternetAddress(to));//指明收件人
        message.setSubject(title);//主题
        String content = getContent("email.ftl", data);
        message.setContent(content,"text/html;charset=utf-8");//内容
        //发送
        transport.sendMessage(message,message.getAllRecipients());
        System.out.println("邮件发送成功");
        //关闭资源
        transport.close();
    }

    // 获取freemarker模板,和添加数据
    public static String getContent(String templateName, Map<String, Object> data) throws TemplateException, IOException {
        // 创建一个Configuration对象，直接new一个对象。构造方法的参数就是freemarker对于的版本号。
        Configuration configuration = new Configuration(Configuration.getVersion());
        // 设置模板文件所在的路径。
        configuration.setDirectoryForTemplateLoading(new File((String) data.get("staticFilePath")));
        // 设置模板文件使用的字符集。一般就是utf-8.
        configuration.setDefaultEncoding("utf-8");
        // 获取模板
        Template template = configuration.getTemplate(templateName, "UTF-8");
        // 填充数据并把模板转为字符串
        return FreeMarkerTemplateUtils.processTemplateIntoString(template, data);
    }


    // 批量发送
    public static void sendEmails(Map<String,Object> data, List<String> emails) throws Exception {
        final String from = "1174013501@qq.com";//给用户发送邮件的邮箱
        final String username = "1174013501@qq.com";//邮箱的用户名
        final String password = "axisuzdlidwniiai";//邮箱授权码
        final String host = "smtp.qq.com";//发送邮件的服务器地址
        final String title = "维数公寓";//邮件主题
        //配置
        Properties properties = new Properties();
        properties.setProperty("mail.host","smtp.qq.com");//设置qq邮件服务器
        properties.setProperty("mail.transport.protocol","smtp");//邮件发送协议
        properties.setProperty("mail.smtp.auth","true"); //需要验证用户名和密码
        //SSL加密
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        properties.put("mail.smtp.ssl.enable",true);
        properties.put("mail.smtp.ssl.socketFactory",sf);
        //创建邮件程序所需环境信息session对象
        Session session = Session.getDefaultInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });
        //开启session的debug模式，可以查看程序发送运行状态
        session.setDebug(true);
        //通过Session得到transport对象
        Transport transport = session.getTransport();
        //使用用户名和授权码连接服务器
        transport.connect(host,username,password);
        // 写邮件 主要专递session
        MimeMessage message = new MimeMessage(session);
        message.setSubject(title);// 主题
        message.setFrom(new InternetAddress(from));// 指明发件人
        message.setRecipients(Message.RecipientType.BCC,InternetAddress.parse(Joiner.on(",").join(emails))); // 抄送人  密送  (bcc密送  cc抄送   to收件)
        // 构造一个带文件路径的File
        DataHandler handler = new DataHandler(new FileDataSource("C:/Users/xuda/Desktop/gc.bat"));
        // 创建一个可以存放多种类型的MimeMultipart对象
        MimeMultipart multipart = new MimeMultipart();
        // 创建相应数据部分 MimeBodyPart
        MimeBodyPart emailFile = new MimeBodyPart();// MimeBodyPart相当于是一层封装，文本、图片、附件各自有封装，最后再封装一次
        emailFile.setDataHandler(handler);// 添加附件
        emailFile.setFileName(MimeUtility.encodeWord("gc.bat", "utf-8", "B"));// 文件名设置编码
        MimeBodyPart emaleContent = new MimeBodyPart();
        emaleContent.setContent("群发测试  带附件", "text/html;charset=UTF-8");// 添加内容
        // 将每个MimeBodyPart对象添加到MimeMultipart中去
        multipart.addBodyPart(emaleContent);// 添加到MimeMultipart 内容
        multipart.addBodyPart(emailFile);// 添加到MimeMultipart 附件
        // 将MimeMultipart对象设置为整个邮件的内容,要主要调用saveChange方法进行更新
        message.setContent(multipart);// // 内容添加到message
        //发送
        transport.sendMessage(message,message.getAllRecipients());
        System.out.println("邮件发送成功");
        //关闭资源
        transport.close();
    }
}
